Part One -- Getting there.

by NymSandra

     Originally this job was called "fool" because a wise person should never speak about what they know. The reason for that is very simple; once you tell about what you know or think is important to others, someone will come along and tell you it's not or will ask about those things which you've left out. The same it seems applies to such routine items as the various modes of basic VGA cards under the mode 13h category. Therefore I have decided to break up the mode 13h tutors into separate topics, each one covering a single aspect. So hang on, here we go into the mode 13h form of display...

Mode 13h

     Oddly enough, most VGA card and monitor combinations can perform a wide variety of different displays, BIOS itself offering us only one out of the total collection. Most of these modes are often referred to by the term 13x or 13hx, but are in fact a group of planar video modes that require special routines to get into and operate properly. A very great deal has been written about them before.

     The three most common variants, and the subject of the last version of this tutor, are the 320 by 200, the 320 by 240, and the 360 by 480 pixel wide and high screens, all with 256 possible colors. Often times you will find these major versions called modes X, Y and Z, but there is also a well known confusion between these labels. Therefore, if you ever need help in any of these modes, it is suggested you say simply mode X and then state the actual dimensions of your screen for clarity. (My own reference book for example refers to the 320 by 240 mode as mode X, while the 320 by 200 is called mode Y, and the 360 by 480 as mode Z. Still other texts use different meanings, the most commonly switched are the X and the Y by definition.)

     However, all of these modes operate in essentially the same way, because each changes key control registers inside the VGA card. Quite a few combinations are possible and used for various purposes. The basic range of possible video modes are;

320x200 (basic mode 13h)
320x175			360x175
320x200 X			360x200
320x240 Y			360x240
320x350			360x350
320x400			360x400
320x480			360x480 Z

     All of these video modes operate with the colors available from the pallet and, with the exception of the basic mode 13h, four pixel planes worth of data across the screen line. If you've never dealt with pixel planes before they are really quite easy, each point of color across the video line hangs upon another block of memory assigned to the video space. This means that pixel 0,0 is on plane 1, pixel 1,0 is on plane 2, etc. Like this;

     The VGA card itself reads these planes in rapid succession, plane 1 then 2, 3 and 4 and back to plane 1. What you see across the screen is the result of the interlace, so how we address each pixel is done through another register in the card; the Plane Mask Register which selects where our data will come and go. But we'll get to that in a moment, let's first see how we go about setting up these various modes.

     All of these video modes are well dated by now, the SVGA card and VESA having taken over the scene. But when you are learning they serve a useful purpose, getting your mind used to thinking in graphics and shaking out the bugs in your idea. So we'll start with the easiest first, then going on to the more complex ones:

Starting A Mode

     As said before the basis of all these modes is to modify the video controller's registers, changing the values to something other than BIOS puts there. Since there are some 60 registers that must be programmed for most any video mode, it is most common to use BIOS to set a mode close to the one desired and then change only those registers that need to be modified for the desired display. All of these modes are variants of the BIOS one, so we make a call to the BIOS 10 hex interrupt with a 13 hex in the AX register, as shown below in assembly language;

     This sets up the screen to a 320 pixel by 200 line mode, with 256 colors available from the palette. However this is the standard mode, which is commonly used because the screen forms exactly one segment available to the CPU. It is therefor rather simple to use and is relatively fast because there is no messing about with the controller registers or pixel planes, so it remains fairly popular. It does not however support multiple pages, nor can be used with fast paste or other screen trickery.

     In the constant quest for good, clean, smooth and fast looking graphics and animations, several programmers stumbled upon the extended modes X, Y and Z. Most of these modes combine the timings of 13h and other screen modes, the details of which you can find in the book, "Programmers guide to the EGA/VGA" by Richard F. Ferraro. (ISBN 0-201-57025-4) For reasons of clarity I will address the X mode first, which I suspect that my book mistakenly calls mode Y. I refer to the planar version of the 320 by 200 pixel mode set by BIOS.

     Getting into this first extended mode is really the easiest of the group, for it requires that we modify only four registers. It does however introduce a new item into our code, that bit plane register for every pixel plotted. You see, most cards today have more memory than a single segment, set into a line very much like the main RAM inside the computer. The trouble is, according to the CPU the screen can only be in one segment at any time, thus there is a conflict of interest going on. This means the video must pull some fancy footwork to get all of it's memory into that one segment. This is called Planar mode, meaning that one plane, or level of an image, can be addressed by the CPU at any one time. The plane mask register controls this value. In addition, we have to tell the card that we want it to do the footwork for us, by setting the other registers to their proper values. Here's how;

     It is common at this point to clear all the planes, usually by writing some color into each of the pixels on the screen. This can be achieved by the following code;

     Now the screen is ready for use. However, finding any one pixel is no longer that easy because each of these four planes overlap one another. Remember that "enable all planes" command from up above? Well that "F" part is the command itself. Since the "F" value in hex is the same as four binary ones, this turns all planes on for reading the CPU data. It also means that the first bank is enabled by a 1 in this place, the second with a 2, the third a 4 (remember, we're talking bits here) and the last with an 8 in the above command. With a bit of programming trickery we can easily reach any pixel, such a sample of that code is presented below;

     Why the times 80 in the middle? I hear you cry. Well, the screen is 320 pixels wide and if you divide that by 4 you get 80 bytes per screen line. That's how the banks work, interlacing each other as the video scans left to right. Reading pixels has the same problem, though you have to remember yet another register in order to do that. Like this;

     Now we can get to the fun stuff, setting the other variants of mode 13h.

     Oddly enough, setting the other styles of mode 13h are really quite similar, and based upon nearly the exact same code. In fact, with the exception of but a few values the code is identical, making similar changes to the registers with the same type of coding. So without any further discussion, here's a sample of how to get into the 320 by 240 pixel mode;

     This process changes the dot clock inside the card, allowing it to display 240 lines in the vertical direction. This is rather a handy mode in some cases, for it means that the pixels are nearly square and a line stepping in both the X and Y directions appears as a 45 degree angle. It also means that you have the "normal" number of pixels plus 40 more lines of them at the bottom, which is handy for a split screen status display or other use. It does however mean that your pixels aren't as tall as the previous two modes, so you may have to readjust your sprites or other drawings. However, this mode also means you can use the same plotting code as above, and you usually have about 3 pages of screens available in memory for page flipping.

     Staying with this same side of the modes I listed above, (that is to say 320 pixels in the horizontal direction) we get to the next variant, that of 320 by 175 lines. Again, this mode uses the exact same code, but if you look closely you will see a change in the data. (Changes marked with -->)

     This piece of code and table will change the screen timing in the vertical direction, essentially "cutting off" the screen at the 175th line. Further variants do the same, by again changing the clock and screen definition values. I am not about to take you through them all, instead I offer a piece of code that will perform this for you, at the bottom of this page.

     As a final example I offer the original text of this tutor page, that code for setting up the screen to the 360 by 480 mode with 256 colors. I myself prefer this mode for doing GUIs, but it is not very useful to the game programmer not using a virtual screen away from the video card. The reason is, you get exactly one page in this mode again, so page flipping is not an option. However, you can still fast paste in this mode and you have a bit of memory left over at the bottom of the card in which to make a "pool" of images. (About 87k pixels, the screen takes 169k.) This screen mode is also handy when you want to learn off-card buffering, so I include it for your reference. Here's how to get into it;

     As you can see, getting into all these modes is actually very similar, only the data, clock and number of registers adjusted has changed. Using this high density mode also means that your pixels will be very short, with over twice as many in the vertical direction as is normal. Slope 1 lines will appear slightly slanted other than 45 degrees, but it can be useful for some things. Lastly, before we go on to the universal code, I'll drop off an example of finding any pixel for the 360 wide modes;

     Yes, it's the same code as before, only with an adjusted multiplier value to equal 90 bytes per line. There are other ways of doing this, some which lend themselves particularly well to SVGA modes and such, but this works for these wide modes. Now on to the universal code;

Universal Mode Setting Code Example

     I'm not sure where I picked this up precisely but it is easy enough to use if you program in ASM.

     If you program in a higher level like C or Pascal you will need a bit of a driver to use it, mostly in saving those registers your compiler requires to prevent it from getting lost. A simple call to this code with the BX register loaded correctly will set any 13h mode you desire, and after that you can work with the screen.

     Remember; use the first version of Set_Pixel for any variation of the 320 pixel wide modes, and the second version of Set_Pixel for those with 360 pixels across the screen.

     I hope this lays to rest any discussion about "forgotten" video modes. (Nyah!)

     See you on the channel!

Write Me


08/04/98

Prog  Next

Go back to home page.

A special thank you goes to Kuwanger99, without whose insistent pestering of me this page would not have been updated.

This page updated to correct a 320x200 error pointed out by Kaiju01 -- Thanks!